package com.tduck.cloud.api.web.ao;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.tduck.cloud.account.entity.OrgEntity;
import com.tduck.cloud.account.entity.UserEntity;
import com.tduck.cloud.account.service.OrgService;
import com.tduck.cloud.account.service.UserService;
import com.tduck.cloud.common.util.RedisUtil;
import com.tduck.cloud.form.dto.*;
import com.tduck.cloud.form.entity.*;
import com.tduck.cloud.form.entity.enums.FormItemTypeEnum;
import com.tduck.cloud.form.entity.enums.FormTypeEnum;
import com.tduck.cloud.form.service.*;
import com.tduck.cloud.form.service.data.FormDataBaseService;
import com.tduck.cloud.form.vo.FormReportDataVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;

import java.util.*;
import java.util.stream.Collectors;

/**
 * ao形式报告
 *
 * @author Guard Baby
 * @date 2023/05/09
 */
@Service("formReportAO")
@Slf4j
@RequiredArgsConstructor
public class FormReportAO {
    private final UserFormDataService userFormDataService;
    private final UserFormItemService userFormItemService;
    private final UserFormService userFormService;
    private final UserService userService;
    private final OrgService orgService;
    private final RedisUtil redisUtil;
    private final FormScoreService formScoreService;
    private final FormDataBaseService formDataBaseService;
    private final FormUserRelationService formUserRelationService;
    private final RelationshipService relationshipService;

    private static final Map<String, Double> SCORE_DIC = new HashMap<>();
//    private static ConcurrentMap<String, String> cacheMap = new ConcurrentHashMap<>();

    private static final String MATRIX_PREFIX = "matrix";

    private static final String USER_FORM_ITEM_KEY = "tduck:formitem:report:";

    private static final String USER_NAME_KEY = "tudck:username:key:";
    private static final String ORG_NAME_KEY = "tudck:orgname:key:";

    private static final long EXPIRE_TIME = 60 * 10L;

    private static final List<FormItemTypeEnum> MATRIX_PLAIN = Lists.newArrayList(FormItemTypeEnum.MATRIX_INPUT, FormItemTypeEnum.MATRIX_SELECT);

    static {
        SCORE_DIC.put("非常满意", 100.0);
        SCORE_DIC.put("满意", 98.0);
        SCORE_DIC.put("基本满意", 96.0);
        SCORE_DIC.put("一般", 90.0);
        SCORE_DIC.put("有点不满意", 85.0);
        SCORE_DIC.put("不满意", 80.0);
        SCORE_DIC.put("非常不满意", 75.0);
    }


    /**
     * 获取综合报告
     *
     * @param formKey 表单key
     * @return {@code FormReportDataVO}
     */
    public FormReportDataVO getReport(String formKey) {

        return getReport(formKey, null);
    }


    public FormReportDataVO getReport(String formKey, Long evaluated) {
        log.debug("getReportStart....");
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("数据查询");
        FormReportDataVO formReportDataVO = new FormReportDataVO();
        UserFormEntity userFormEntity = userFormService.query().eq("form_key", formKey).one();
//        QueryWrapper<UserFormDataEntity> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("form_key", formKey);
//        List<UserFormDataEntity> dataEntityList = userFormDataService.list(queryWrapper);
//        String sql = "select * from  fm_user_form_data WHERE form_key = '%s'";
        List<UserFormDataEntity> dataEntityList = formDataBaseService.queryDataByFormKey(formKey);
        formReportDataVO.setUserFormEntity(userFormEntity);
        stopWatch.stop();
        log.debug(stopWatch.prettyPrint());
        stopWatch.start("数据展开");
        List<FormReportDetailDTO> formReportDetails = expandData(userFormEntity, dataEntityList, evaluated);
        stopWatch.stop();
        log.debug(stopWatch.prettyPrint());
        stopWatch.start("平均得分计算");
        List<EvaluatedScoreDTO> evaluatedScores = queryScoreDataByFormKey(formReportDetails);
        stopWatch.stop();
        log.debug(stopWatch.prettyPrint());
        stopWatch.start("按问题得分计算");
        List<FormItemScoreDTO> formItemScoreDTOList = queryItemScoreByFormKey(formReportDetails);
        stopWatch.stop();
        log.debug(stopWatch.prettyPrint());
        if (Objects.nonNull(evaluated) && FormTypeEnum.ORG.equals(userFormEntity.getType())) {
            //单个部门评价结果过滤
            evaluatedScores = evaluatedScores.stream().filter(f -> f.getEvaluated().equals(evaluated)).collect(Collectors.toList());
            for (FormItemScoreDTO formItemScoreDTO : formItemScoreDTOList) {
                List<EvaluatedScoreDTO> detailList = formItemScoreDTO.getDetailList();
                if (CollUtil.isNotEmpty(detailList)) {
                    detailList = detailList.stream().filter(f -> f.getEvaluated().equals(evaluated)).collect(Collectors.toList());
                    formItemScoreDTO.setDetailList(detailList);
                }
            }
        }
        formReportDataVO.setEvaluatedScoreDTOList(evaluatedScores);
        formReportDataVO.setFormItemScoreDTOList(formItemScoreDTOList);
        return formReportDataVO;
    }

    /**
     * 计算每个被评价者的总分平均分
     *
     * @param formKey 形成关键
     * @return {@code List<EvaluatedScoreDTO>}
     */
    public List<EvaluatedScoreDTO> queryScoreDataByFormKey(String formKey) {
        //将数据展开
        List<FormReportDetailDTO> formReportDetails = expandData(formKey);
        return queryScoreDataByFormKey(formReportDetails);
    }

    /**
     * 计算每个被评价者的总分平均分
     *
     * @param formReportDetails 答卷数据展开
     * @return {@code List<EvaluatedScoreDTO>}
     */
    public List<EvaluatedScoreDTO> queryScoreDataByFormKey(List<FormReportDetailDTO> formReportDetails) {
        //过滤出矩阵选择
        // 计算每个人的平均分
        List<EvaluatedScoreDTO> evaluatedScores = new ArrayList<>();
        //按照被评价人分组
        if (FormTypeEnum.ORG.equals(formReportDetails.get(0).getFormType())) {
            formReportDetails = formReportDetails.stream().filter(f -> FormItemTypeEnum.MATRIX_SELECT.equals(f.getFormItemType())).collect(Collectors.toList());
            Map<Long, List<FormReportDetailDTO>> subDataMap = formReportDetails.stream().collect(Collectors.groupingBy(FormReportDetailDTO::getEvaluated));
            for (Map.Entry<Long, List<FormReportDetailDTO>> entry : subDataMap.entrySet()) {
                EvaluatedScoreDTO evaluatedScoreDTO = new EvaluatedScoreDTO();
                Long evaluated = entry.getKey();
                List<FormReportDetailDTO> subList = entry.getValue();
                Double subScore = subList.stream().mapToDouble(FormReportDetailDTO::getScore).sum();
                evaluatedScoreDTO.setEvaluated(evaluated);
                evaluatedScoreDTO.setEvaluatedName(subList.get(0).getEvaluatedName());
                //计算被评价人的被评价次数
                int count = formReportDetails.stream().filter(f -> evaluated.equals(f.getEvaluated())).collect(Collectors.groupingBy(FormReportDetailDTO::getFormDataId)).size();
                evaluatedScoreDTO.setAverage(NumberUtil.div(subScore, Double.valueOf(count), 2));
                evaluatedScores.add(evaluatedScoreDTO);
            }
        }else if (FormTypeEnum.PERSON.equals(formReportDetails.get(0).getFormType())){
            //todo-lx 360人才盘点
            List<FormReportDetail360DTO> formReportDetail360DTOS = BeanUtil.copyToList(formReportDetails,FormReportDetail360DTO.class);
            Map<Long, List<FormReportDetail360DTO>> subDataMap = formReportDetail360DTOS.stream().filter(f -> FormItemTypeEnum.MATRIX_SCALE.equals(f.getFormItemType())).collect(Collectors.groupingBy(FormReportDetail360DTO::getUserRelationId));
            for (Map.Entry<Long, List<FormReportDetail360DTO>> entry : subDataMap.entrySet()) {
                EvaluatedScore360DTO evaluatedScore360DTO = new EvaluatedScore360DTO();
                Long userRelationId = entry.getKey();
                List<FormReportDetail360DTO> subList = entry.getValue();
//                Long evaluated = subList.get(0).getEvaluated();
                Double subScore = subList.stream().mapToDouble(FormReportDetail360DTO::getScore).sum();
                evaluatedScore360DTO.setUserRelationId(userRelationId);
                evaluatedScore360DTO.setUserRelationName(subList.get(0).getUserRelationName());
                int count = formReportDetail360DTOS.stream().filter(f -> userRelationId.equals(f.getUserRelationId())).collect(Collectors.groupingBy(FormReportDetailDTO::getFormDataId)).size();
                evaluatedScore360DTO.setAverage(NumberUtil.div(subScore, Double.valueOf(count), 2));
                evaluatedScores.add(evaluatedScore360DTO);
            }
        }
        //计算总体平均分
        if (CollUtil.isNotEmpty(evaluatedScores)) {
            double totalAverage = evaluatedScores.stream().mapToDouble(EvaluatedScoreDTO::getAverage).average().getAsDouble();
            log.debug("总体平均分：{}", totalAverage);
            for (EvaluatedScoreDTO evaluatedScoreDTO : evaluatedScores) {
                evaluatedScoreDTO.setTotalAverage(NumberUtil.round(totalAverage, 2).doubleValue());
            }
        }
        log.debug("evaluatedScores:{}", JSON.toJSONString(evaluatedScores));
        return evaluatedScores.stream().sorted(Comparator.comparing(EvaluatedScoreDTO::getAverage).reversed()).collect(Collectors.toList());
    }

    /**
     * 按问题统计得分
     *
     * @param formReportDetails 答卷数据展开
     * @return {@code List<FormItemScoreDTO>}
     */
    public List<FormItemScoreDTO> queryItemScoreByFormKey(List<FormReportDetailDTO> formReportDetails) {
        List<FormItemScoreDTO> itemScores = new ArrayList<>();
        // 根据问题id和答题人id分类
        Map<String, List<FormReportDetailDTO>> MatrixSelectSubMap = formReportDetails.stream().collect(Collectors.groupingBy(FormReportDetailDTO::getFormItemId));
        for (Map.Entry<String, List<FormReportDetailDTO>> entry : MatrixSelectSubMap.entrySet()) {
            String formItemId = entry.getKey();
            FormItemScoreDTO formItemScore = new FormItemScoreDTO();
            formItemScore.setFormItemId(formItemId);
            formItemScore.setTitle(entry.getValue().get(0).getFormItemTitle());
            formItemScore.setFormType(entry.getValue().get(0).getFormType());
            formItemScore.setDetailList(queryScoreDataByFormKey(entry.getValue()));
            itemScores.add(formItemScore);
        }
        return itemScores;
    }

    private List<FormItemScoreDTO> handleMatrixSelectItemScore(List<FormReportDetailDTO> formReportDetails) {
        List<FormItemScoreDTO> itemScores = new ArrayList<>();
        // 根据问题id和答题人id分类
        Map<String, List<FormReportDetailDTO>> matrixSelectSubMap = formReportDetails.stream().filter(f -> FormItemTypeEnum.MATRIX_SELECT.equals(f.getFormItemType())).collect(Collectors.groupingBy(FormReportDetailDTO::getFormItemId));
        for (Map.Entry<String, List<FormReportDetailDTO>> entry : matrixSelectSubMap.entrySet()) {
            String formItemId = entry.getKey();
            FormItemScoreDTO formItemScore = new FormItemScoreDTO();
            formItemScore.setFormItemId(formItemId);
            formItemScore.setTitle(entry.getValue().get(0).getFormItemTitle());
            formItemScore.setFormType(entry.getValue().get(0).getFormType());
            formItemScore.setDetailList(queryScoreDataByFormKey(entry.getValue()));
            itemScores.add(formItemScore);
        }
        return itemScores;
    }

    private List<FormItemScoreDTO> handleMatrixScaleItemScore(List<FormReportDetailDTO> formReportDetails) {
        List<FormItemScoreDTO> itemScores = new ArrayList<>();
        Map<String, List<FormReportDetailDTO>> matrixScaleSubMap = formReportDetails.stream().filter(f -> FormItemTypeEnum.MATRIX_SCALE.equals(f.getFormItemType())).collect(Collectors.groupingBy(FormReportDetailDTO::getFormItemId));
        for (Map.Entry<String, List<FormReportDetailDTO>> entry : matrixScaleSubMap.entrySet()) {
            String formItemId = entry.getKey();
            List<FormReportDetailDTO> reportDetailList = entry.getValue();
            FormItemScoreDTO formItemScoreDTO = new FormItemScoreDTO();
        }

        return itemScores;
    }

    /**
     * 按问题统计得分
     *
     * @param formKey 表单key
     * @return {@code List<FormItemScoreDTO>}
     */
    public List<FormItemScoreDTO> queryItemScoreByFormKey(String formKey) {
        List<FormReportDetailDTO> formReportDetails = expandData(formKey);
        return queryItemScoreByFormKey(formReportDetails);
    }

    /**
     * 展开数据
     *
     * @param formKey 表单key
     * @return {@code List<FormDataVo>}
     */
    public List<FormReportDetailDTO> expandData(String formKey) {
        return expandData(formKey, null);
    }

    public List<FormReportDetailDTO> expandData(String formKey, Long evaluated) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("expandData query");
        UserFormEntity userFormEntity = userFormService.query().eq("form_key", formKey).one();
//        List<UserFormDataEntity> dataEntityList = userFormDataService.query().eq("form_key", formKey).list();
        List<UserFormDataEntity> dataEntityList = formDataBaseService.queryDataByFormKey(formKey);
        stopWatch.stop();
        log.debug(stopWatch.prettyPrint());
        return expandData(userFormEntity, dataEntityList, evaluated);

    }

    /**
     * 展开数据
     *
     * @param userFormEntity 用户表单
     * @param dataEntityList 答卷数据
     * @return {@code List<FormReportDetailDTO>}
     */
    private List<FormReportDetailDTO> expandData(UserFormEntity userFormEntity, List<UserFormDataEntity> dataEntityList, Long evaluated) {
        log.debug("expandData start.....");
        List<FormScoreEntity> formScoreEntities = formScoreService.query().eq("form_key", userFormEntity.getFormKey()).list();
        List<FormReportDetailDTO> formReportDetails = new ArrayList<>();
        FormTypeEnum formType = userFormEntity.getType();
        if (CollUtil.isNotEmpty(dataEntityList)) {
//            log.debug("dataEntityList:{}", JSON.toJSONString(dataEntityList));
            for (UserFormDataEntity userFormDataEntity : dataEntityList) {
//                log.info(JSON.toJSONString(userFormDataEntity));
                Map<String, Object> originalData = userFormDataEntity.getOriginalData();
                for (Map.Entry<String, Object> data : originalData.entrySet()) {
                    String formItemId = data.getKey();
                    if (!formItemId.startsWith(MATRIX_PREFIX)) {
                        continue;
                    }
                    UserFormItemEntity userFormItemEntity;
                    String key = USER_FORM_ITEM_KEY + formItemId;
                    Object formItemObj = redisUtil.get(key);
                    if (Objects.isNull(formItemObj)) {
                        userFormItemEntity = userFormItemService.query().eq("form_item_id", formItemId).one();
                        redisUtil.set(key, JSON.toJSONString(userFormItemEntity), EXPIRE_TIME);
                    } else {
                        userFormItemEntity = JSON.parseObject(redisUtil.get(key).toString(), UserFormItemEntity.class);
                    }
                    if (FormItemTypeEnum.MATRIX_SELECT.equals(userFormItemEntity.getType())) {
                        formReportDetails.addAll(handelMatrixSelect(data, userFormItemEntity, userFormDataEntity, formScoreEntities, userFormEntity));
                    } else if (FormItemTypeEnum.MATRIX_INPUT.equals(userFormItemEntity.getType())) {
                        formReportDetails.addAll(handelMatrixInput(data, userFormItemEntity, userFormDataEntity, userFormEntity, formType, evaluated));
                    } else if (FormItemTypeEnum.MATRIX_SCALE.equals(userFormItemEntity.getType())) {
                        formReportDetails.addAll(handelMatrixScale(data, userFormItemEntity, userFormDataEntity, userFormEntity, formType, evaluated));
                    }
                }
            }
        }
        return formReportDetails;
    }

    private List<FormReportDetail360DTO> handelMatrixScale(Map.Entry<String, Object> data, UserFormItemEntity userFormItemEntity, UserFormDataEntity userFormDataEntity, UserFormEntity userFormEntity, FormTypeEnum formType, Long evaluated) {
        if (!FormTypeEnum.PERSON.equals(formType)) {
            return null;
        }
        List<FormReportDetail360DTO> formReportDetails = new ArrayList<>();
        //todo-lx 计算matrix-scale 组件得分
        List<RelationshipEntity> relationshipEntityList = relationshipService.query().eq("form_key", userFormEntity.getFormKey()).eq("evaluated", evaluated).list();
        Map<Long, Long> relationMap = relationshipEntityList.stream().collect(Collectors.toMap(RelationshipEntity::getEvaluator, RelationshipEntity::getUserRelationId));
        List<FormUserRelationEntity> userRelationEntities = formUserRelationService.query().eq("form_key", userFormDataEntity.getFormKey()).list();
        Map<Long,  List<FormUserRelationEntity>> userRelationMap = userRelationEntities.stream().collect(Collectors.groupingBy(FormUserRelationEntity::getId));
        Map<String, Object> matrixSelectMap = JSON.parseObject(JSON.toJSONString(data.getValue()), Map.class);
        log.debug("matrixSelectObj:{}", matrixSelectMap);
        Long evaluator = userFormDataEntity.getAcUserId();
        for (Map.Entry<String, Object> entry : matrixSelectMap.entrySet()) {
            FormReportDetail360DTO formReportDetail360DTO = new FormReportDetail360DTO();
            Long evaluatedId = Long.valueOf(entry.getKey());
            Double score = Double.valueOf(entry.getValue().toString());
            if (Objects.nonNull(evaluated) && !Objects.equals(evaluated, evaluatedId)) {
                //仅获取当前被评价人的评分结果
                continue;
            }
            formReportDetail360DTO.setScore(score);
            formReportDetail360DTO.setFormDataId(userFormDataEntity.getId());
            formReportDetail360DTO.setFormKey(userFormDataEntity.getFormKey());
            formReportDetail360DTO.setFormType(formType);
            formReportDetail360DTO.setEvaluated(evaluatedId);
            formReportDetail360DTO.setEvaluatedName(getEvaluatedName(formType, evaluatedId));
            formReportDetail360DTO.setEvaluator(evaluator);
            formReportDetail360DTO.setEvaluatorName(getEvaluatorName(evaluator));
            formReportDetail360DTO.setUserRelationId(relationMap.get(evaluator));
            FormUserRelationEntity formUserRelationEntity = userRelationMap.get(formReportDetail360DTO.getUserRelationId()).get(0);
            formReportDetail360DTO.setUserRelationName(formUserRelationEntity.getName());
            formReportDetail360DTO.setFormItemType(userFormItemEntity.getType());
            formReportDetail360DTO.setFormItemTitle(userFormItemEntity.getTextLabel());
            formReportDetail360DTO.setFormItemId(userFormItemEntity.getFormItemId());
            formReportDetail360DTO.setRate(formUserRelationEntity.getRate());
            formReportDetails.add(formReportDetail360DTO);
        }
        return formReportDetails;
    }

    /**
     * 汉德尔矩阵输入
     *
     * @param data               数据
     * @param userFormItemEntity 用户表单项实体
     * @param userFormDataEntity 用户表单数据实体
     * @param userFormEntity     用户实体形式
     * @param formType           表单类型
     * @param evaluated          被评估人
     * @return {@code List<FormReportDetailDTO>}
     */
    private List<FormReportDetailDTO> handelMatrixInput(Map.Entry<String, Object> data, UserFormItemEntity userFormItemEntity, UserFormDataEntity userFormDataEntity, UserFormEntity userFormEntity, FormTypeEnum formType, Long evaluated) {
        List<FormReportDetailDTO> formReportDetails = new ArrayList<>();
        Map<String, Object> score = JSON.parseObject(JSON.toJSONString(data.getValue()), Map.class);
//                        log.info(score.toString());
        for (Map.Entry<String, Object> entry : score.entrySet()) {
            if (Objects.nonNull(evaluated) && !Objects.equals(evaluated, Long.valueOf(entry.getKey()))) {
                continue;
            }
            FormReportDetailDTO formReportDetail = new FormReportDetailDTO();
            formReportDetail.setEvaluated(Long.valueOf(entry.getKey()));
            formReportDetail.setEvaluatedName(getEvaluatedName(formType, formReportDetail.getEvaluated()));
            formReportDetail.setFormItemType(userFormItemEntity.getType());
            formReportDetail.setFormItemId(userFormItemEntity.getFormItemId());
            formReportDetail.setFormItemTitle(userFormItemEntity.getTextLabel());
            formReportDetail.setEvaluator(userFormDataEntity.getAcUserId());
            formReportDetail.setEvaluatorName(getEvaluatorName(userFormDataEntity.getAcUserId()));
            formReportDetail.setId(userFormDataEntity.getId());
            formReportDetail.setFormType(userFormEntity.getType());
            formReportDetail.setFormKey(userFormEntity.getFormKey());
            JSONObject answer = JSON.parseObject(entry.getValue().toString());
//                            log.debug("answer:{}", answer);
            String answerStr = StringUtils.EMPTY;
            for (String answerKey : answer.keySet()) {
                answerStr = answer.getString(answerKey);
            }
            formReportDetail.setPlainText(answerStr);
            formReportDetails.add(formReportDetail);
        }
        return formReportDetails;
    }

    private String getEvaluatorName(Long evaluatorId) {
        String userNameCacheKey = USER_NAME_KEY + String.valueOf(evaluatorId);
        Object evaluatorName = redisUtil.get(userNameCacheKey);
        if (Objects.nonNull(evaluatorName)) {
            return (String) evaluatorName;
        } else {
            UserEntity userEntity = userService.getById(evaluatorId);
            redisUtil.set(userNameCacheKey, userEntity.getName(), EXPIRE_TIME);
            return userEntity.getName();
        }
    }

    private String getEvaluatedName(FormTypeEnum formType, Long evaluatedId) {
        String key = (FormTypeEnum.ORG.equals(formType) ? ORG_NAME_KEY : USER_NAME_KEY) + evaluatedId;
        Object evaluatedName = redisUtil.get(key);
        if (Objects.nonNull(evaluatedName)) {
            return evaluatedName.toString();
        } else if (FormTypeEnum.ORG.equals(formType)) {
            OrgEntity orgEntity = orgService.getById(evaluatedId);
            redisUtil.set(key, orgEntity.getName(), EXPIRE_TIME);
            return orgEntity.getName();
        } else if (FormTypeEnum.PERSON.equals(formType)) {
            UserEntity user = userService.getById(evaluatedId);
            redisUtil.set(key, user.getName(), EXPIRE_TIME);
            return user.getName();
        }
        return null;
    }

    /**
     * 处理矩阵选择
     *
     * @param data               数据
     * @param userFormItemEntity 用户表单项实体
     * @param userFormDataEntity 用户表单数据实体
     * @param formScoreEntities  形式分实体
     * @param userFormEntity     用户实体形式
     * @return {@code List<FormReportDetailDTO>}
     */
    private List<FormReportDetailDTO> handelMatrixSelect(Map.Entry<String, Object> data, UserFormItemEntity userFormItemEntity, UserFormDataEntity userFormDataEntity, List<FormScoreEntity> formScoreEntities, UserFormEntity userFormEntity) {
        List<FormReportDetailDTO> result = new ArrayList<>();
        JSONObject matrixSelectObj = JSON.parseObject(JSON.toJSONString(data.getValue()));
        JSONArray matrixRowObj = matrixSelectObj.getJSONArray("rows");
        for (int i = 0; i < matrixRowObj.size(); i++) {
            JSONObject row = matrixRowObj.getJSONObject(i);
            Long evaluatedId = row.getLong("id");
            String evaluatedName = row.getString("label");
            String colInput = row.getString("colInput");
            String label = row.getString("text");
            FormReportDetailDTO formReportDetail = new FormReportDetailDTO();
            formReportDetail.setFormDataId(userFormDataEntity.getId());
            formReportDetail.setEvaluated(evaluatedId);
            formReportDetail.setEvaluatedName(evaluatedName);
            formReportDetail.setFormItemType(userFormItemEntity.getType());
            if (CollUtil.isNotEmpty(formScoreEntities)) {
                for (FormScoreEntity formScoreEntity : formScoreEntities) {
                    if (formScoreEntity.getLabel().equals(label)) {
                        formReportDetail.setScore(formScoreEntity.getScore());
                        break;
                    }
                }
            } else {
                formReportDetail.setScore(SCORE_DIC.get(label));
            }
            formReportDetail.setFormItemId(userFormItemEntity.getFormItemId());
            formReportDetail.setFormItemTitle(userFormItemEntity.getTextLabel());
            formReportDetail.setEvaluator(userFormDataEntity.getAcUserId());
            String key = USER_NAME_KEY + userFormDataEntity.getAcUserId();
            Object evaluatorName = redisUtil.get(key);
            if (Objects.nonNull(evaluatorName)) {
                formReportDetail.setEvaluatorName((String) evaluatorName);
            } else {
                UserEntity userEntity = userService.getById(userFormDataEntity.getAcUserId());
                redisUtil.set(key, userEntity.getName(), EXPIRE_TIME);
                formReportDetail.setEvaluatorName(userEntity.getName());
            }
            formReportDetail.setId(userFormDataEntity.getId());
            formReportDetail.setFormType(userFormEntity.getType());
            formReportDetail.setFormKey(userFormEntity.getFormKey());
            formReportDetail.setScoreText(label);
            if (StrUtil.isNotBlank(colInput)) {
                formReportDetail.setPlainText(formReportDetail.getScoreText() + ":  " + colInput);
            }
            result.add(formReportDetail);
        }
        return result;

    }

    /**
     * 查询主观评价
     *
     * @param formKey   形成关键
     * @param evaluated 评估
     * @return {@code List<FormTextItemScoreDTO>}
     */
    public List<FormTextItemScoreDTO> queryFormTextItemScore(String formKey, Long evaluated) {
        return queryFormTextItemScore(expandData(formKey), evaluated);
    }

    /**
     * 针对个人的主观评价
     *
     * @param formReportDetails 原始数据
     * @param evaluated         被评价者id
     * @return {@code List<FormTextItemScoreDTO>}
     */
    private List<FormTextItemScoreDTO> queryFormTextItemScore(List<FormReportDetailDTO> formReportDetails, Long evaluated) {
        log.debug("queryFormTextItemScore start....");
        List<FormTextItemScoreDTO> scoreDTOS = Lists.newArrayList();
        //过滤出矩阵填空
        formReportDetails = formReportDetails.stream().filter(f -> MATRIX_PLAIN.contains(f.getFormItemType()) && StrUtil.isNotBlank(f.getPlainText()) && evaluated.equals(f.getEvaluated())).collect(Collectors.toList());
        //按照问题分组
        Map<String, List<FormReportDetailDTO>> subMapData = formReportDetails.stream().collect(Collectors.groupingBy(FormReportDetailDTO::getFormItemId));
        for (Map.Entry<String, List<FormReportDetailDTO>> entry : subMapData.entrySet()) {
            FormTextItemScoreDTO formTextItemScoreDTO = new FormTextItemScoreDTO();
            List<FormTextItemScoreDetailDTO> detailList = new ArrayList<>();
            List<FormReportDetailDTO> subList = entry.getValue();
            for (FormReportDetailDTO detail : subList) {
                if (StrUtil.isBlank(detail.getPlainText())) {
                    continue;
                }
                FormTextItemScoreDetailDTO formTextItemScoreDetailDTO = new FormTextItemScoreDetailDTO();
                long count = detailList.stream().filter(f -> f.getText().equals(detail.getPlainText())).count();
                if (count > 0) {
                    for (FormTextItemScoreDetailDTO itemScoreDTO : detailList) {
                        if (itemScoreDTO.getText().equals(detail.getPlainText())) {
                            itemScoreDTO.setCount(itemScoreDTO.getCount() + 1);
                            break;
                        }
                    }
                    continue;
                }
                formTextItemScoreDetailDTO.setText(detail.getPlainText());
                formTextItemScoreDetailDTO.setCount(1);
                detailList.add(formTextItemScoreDetailDTO);
            }
            formTextItemScoreDTO.setEvaluated(subList.get(0).getEvaluated());
            formTextItemScoreDTO.setEvaluatedName(subList.get(0).getEvaluatedName());
            formTextItemScoreDTO.setText(subList.get(0).getFormItemTitle());
            formTextItemScoreDTO.setDetailList(detailList);
            scoreDTOS.add(formTextItemScoreDTO);
        }
        log.debug("queryFormTextItemScore end....");
        return scoreDTOS;
    }
}
